﻿using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Sidvall.Data
{
    public sealed class Filter<TField> : IFilterItem
    {
        #region Public Members

        public Sidvall.Data.LogicalOperator LogicalOperator { get; set; }

        #region ChildFilters

        private FilterCollection<TField> _ChildFilters;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public FilterCollection<TField> ChildFilters
        {
            get
            {
                if (_ChildFilters == null)
                    _ChildFilters = new FilterCollection<TField>();
                return _ChildFilters;
            }
            set
            {
                _ChildFilters = value;
            }
        }

        #endregion
        #region FilterItems

        private FilterItemCollection<TField> _FilterItems;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public FilterItemCollection<TField> FilterItems
        {
            get
            {
                if (_FilterItems == null)
                    _FilterItems = new FilterItemCollection<TField>();
                return _FilterItems;
            }
            set
            {
                _FilterItems = value;
            }
        }

        #endregion

        #region AddChildFilter

        public Filter<TField> AddChildFilter(Filter<TField> item)
        {
            if (item == null)
                return null;

            this.ChildFilters.Add(item);

            return item;
        }
        public Filter<TField> AddChildFilter(Sidvall.Data.LogicalOperator logicalOperator)
        {
            Filter<TField> item;

            item = new Filter<TField>(logicalOperator);

            return AddChildFilter(item);
        }

        #endregion
        #region AddCustomFilterItem

        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, object value, DataType dataType)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeObject(value, dataType), dataType, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, bool value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Boolean, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, byte value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Byte, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, char value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Char, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, System.DateTime value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.DateTime, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, System.DateTimeOffset value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.DateTimeOffset, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, decimal value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Decimal, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, double value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Double, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, short value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Int16, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, int value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Int32, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, long value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Int64, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, float value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Single, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, string value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.String, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, System.TimeSpan value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.TimeSpan, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, byte[] value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Binary, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, Sidvall.Data.Geography value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Geography, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, Sidvall.Data.Geometry value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Geometry, false);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, System.Enum value)
        {
            System.Type enumType, valueType;
            object enumValue;

            if (value == null)
                return null;
            enumType = value.GetType();
            if (!System.Enum.IsDefined(enumType, value))
                return null;
            valueType = System.Enum.GetUnderlyingType(enumType);
            enumValue = System.Enum.Parse(enumType, value.ToString(), true);
            if (valueType == typeof(System.Byte))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((byte)enumValue), DataType.Byte, false);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int16))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((short)enumValue), DataType.Int16, false);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int32))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((int)enumValue), DataType.Int32, false);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int64))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((long)enumValue), DataType.Int64, false);
                Add(item);
                return item;
            }
            return null;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, IEnumerable<byte> value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Byte, true);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, IEnumerable<short> value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Int16, true);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, IEnumerable<int> value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Int32, true);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, IEnumerable<long> value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Int64, true);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, IEnumerable<string> value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.String, true);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem(string fieldName, ComparisonOperator comparisonOperator, IEnumerable<System.Guid> value)
        {
            var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Guid, true);
            Add(item);
            return item;
        }
        public FilterItem AddCustomFilterItem<T>(string fieldName, ComparisonOperator comparisonOperator, IEnumerable<T> value) where T : struct
        {
            System.Type enumType, valueType;

            if (value == null)
                return null;
            enumType = value.GetType().GenericTypeArguments[0];
            valueType = System.Enum.GetUnderlyingType(enumType);
            if (valueType == typeof(System.Byte))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<byte>()), DataType.Byte, true);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int16))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<short>()), DataType.Int16, true);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int32))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<int>()), DataType.Int32, true);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int64))
            {
                var item = new FilterItem(fieldName, comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<long>()), DataType.Int64, true);
                Add(item);
                return item;
            }
            return null;
        }

        #endregion
        #region AddFilterItem

        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, object value, DataType dataType)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeObject(value, dataType), dataType, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, bool value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Boolean, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, byte value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Byte, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, char value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Char, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, System.DateTime value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.DateTime, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, System.DateTimeOffset value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.DateTimeOffset, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, System.Guid value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Guid, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, decimal value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Decimal, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, double value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Double, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, short value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Int16, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, int value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Int32, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, long value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Int64, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, float value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Single, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, string value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.String, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, System.TimeSpan value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.TimeSpan, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, byte[] value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize(value), DataType.Binary, false);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, System.Enum value)
        {
            System.Type enumType, valueType;
            object enumValue;

            if (value == null)
                return null;
            enumType = value.GetType();
            if (!System.Enum.IsDefined(enumType, value))
                return null;
            valueType = System.Enum.GetUnderlyingType(enumType);
            enumValue = System.Enum.Parse(enumType, value.ToString(), true);
            if (valueType == typeof(System.Byte))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((byte)enumValue), DataType.Byte, false);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int16))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((short)enumValue), DataType.Int16, false);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int32))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((int)enumValue), DataType.Int32, false);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int64))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.Serialize((long)enumValue), DataType.Int64, false);
                Add(item);
                return item;
            }
            return null;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, IEnumerable<byte> value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Byte, true);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, IEnumerable<short> value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Int16, true);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, IEnumerable<int> value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Int32, true);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, IEnumerable<long> value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Int64, true);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, IEnumerable<string> value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.String, true);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem(TField fieldId, ComparisonOperator comparisonOperator, IEnumerable<System.Guid> value)
        {
            var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value), DataType.Guid, true);
            Add(item);
            return item;
        }
        public FilterItem AddFilterItem<T>(TField fieldId, ComparisonOperator comparisonOperator, IEnumerable<T> value) where T : struct
        {
            System.Reflection.TypeInfo valueTypeInfo;
            System.Type enumType, valueType;

            if (value == null)
                return null;
            valueTypeInfo = value.GetType().GetTypeInfo();
            if ((valueTypeInfo.GenericTypeArguments != null) && (valueTypeInfo.GenericTypeArguments.Length > 0))
                enumType = valueTypeInfo.GenericTypeArguments[0];
            else
                enumType = valueTypeInfo.GetElementType();
            valueType = System.Enum.GetUnderlyingType(enumType);
            if (valueType == typeof(System.Byte))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<byte>()), DataType.Byte, true);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int16))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<short>()), DataType.Int16, true);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int32))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<int>()), DataType.Int32, true);
                Add(item);
                return item;
            }
            else if (valueType == typeof(System.Int64))
            {
                var item = new FilterItem(fieldId.ToString(), comparisonOperator, Sidvall.Serialization.SerializerManager.Current.SerializeArray(value.Cast<long>()), DataType.Int64, true);
                Add(item);
                return item;
            }
            return null;
        }

        #endregion
        #region Copy

        public Filter<TField> Copy()
        {
            Filter<TField> item;

            item = new Filter<TField>()
            {
                ChildFilters = this.ChildFilters.Copy(),
                FilterItems = this.FilterItems.Copy(),
                LogicalOperator = this.LogicalOperator,
            };
            return item;
        }

        #endregion
        #region CreateParentFilter

        public Filter<TField> CreateParentFilter(Sidvall.Data.LogicalOperator logicalOperator)
        {
            Filter<TField> item;

            item = new Filter<TField>()
            {
                LogicalOperator = logicalOperator,
            };
            item.AddChildFilter(this);

            return item;
        }

        #endregion
        #region EnsureValidFilter

        public void EnsureValidFilter(Sidvall.Data.LogicalOperator logicalOperator, bool requireAllParameters, params string[] parameters)
        {
            EnsureValidFilter(logicalOperator, requireAllParameters, parameters.AsEnumerable());
        }
        public void EnsureValidFilter(Sidvall.Data.LogicalOperator logicalOperator, bool requireAllParameters, IEnumerable<string> parameters)
        {
            this.ChildFilters.Clear();
            this.LogicalOperator = logicalOperator;
            if (parameters != null)
            {
                int iMax = this.FilterItems.Count;
                for (int i = iMax - 1; i >= 0; i--)
                {
                    var filterItem = this.FilterItems[i];
                    if (!parameters.Contains(filterItem.FieldName))
                        this.FilterItems.Remove(filterItem);
                }
                if (requireAllParameters)
                {
                    if (this.FilterItems.Count != parameters.Count())
                        throw new Sidvall.Security.UnauthorizedException();
                }
            }
        }

        #endregion
        #region ToString

        public override string ToString()
        {
            return Sidvall.SystemContext.Current.SqlManager.GetSqlWhere(this);
        }

        #endregion

        #region IFilterItem Members

        string IFilterItem.FieldName
        {
            get
            {
                return string.Empty;
            }
        }
        ComparisonOperator IFilterItem.ComparisonOperator
        {
            get
            {
                return ComparisonOperator.Equal;
            }
        }
        object IFilterItem.Value
        {
            get
            {
                return null;
            }
        }
        DataType IFilterItem.ValueDataType
        {
            get
            {
                return DataType.Object;
            }
        }
        bool IFilterItem.ValueIsArray
        {
            get
            {
                return false;
            }
        }
        ICollection<IFilterItem> IFilterItem.GetSubFilters()
        {
            List<IFilterItem> items;

            items = new List<IFilterItem>(this.FilterItems);
            items.AddRange(this.ChildFilters);

            return items;
        }

        #endregion

        #endregion
        #region Private Members

        #region Add

        private void Add(FilterItem item)
        {
            this.FilterItems.Add(item);
        }

        #endregion

        #endregion
        #region Constructors

        public Filter()
        {
            this.LogicalOperator = Data.LogicalOperator.And;
        }
        public Filter(Sidvall.Data.LogicalOperator logicalOperator)
        {
            this.LogicalOperator = logicalOperator;
        }

        #endregion
    }
}
